#ifndef _POSTGRES_DRIVER_H_
#define _POSTGRES_DRIVER_H_

#include <buildspec.h>
#include <Client/ClientUtils/Network/RDBDriverInterface.h>
#include <Client/ClientUtils/Network/NetworkInterface.h>
#include <Client/ClientUtils/Network/pg/PGAccess.h>

#include <boost/scoped_ptr.hpp>

#include <sstream>

#include <pqxx/pqxx>


namespace GST {
namespace ClientUtils {

	/**
	 * Retreiving data from a postgres database
	 */
	class GST_API_EXPORT PostgresDriver
		: public RDBDriverInterface
	{
		friend class PGAccess;

	public:
		//local typedefs:
		typedef boost::shared_ptr<pqxx::result> PQXXResultPtr;

		//c'tors and d'tors
		PostgresDriver(HostPtr host, const std::string& dbname);
		virtual ~PostgresDriver() {}		

		///@name RDB interface
		//@{
		virtual void connect();
		virtual void disconnect();
		virtual bool isConnected();
		virtual int getPID();
		//virtual TableAttributeDescListPtr ListTableAttributeDescs(const std::string& tableName);
		virtual void exec(const std::string & sqlStatement);
		/**
		 * calls preparedHandle.exec() and handles exceptions the same as
		 * GST::ClientUtils::PostgresDriver::execute(const std::string & sql)
		 *
		 * @note this is mostly useful for prepared statements of GST stored
		 * procedure calls to get back the correct GST exception type
		 */
		virtual PQXXResultPtr executePreparedStatement(pqxx::prepare::invocation preparedHandle) const;
		virtual AbstractDataTablePtr exec_returning(const std::string & sqlStatement);
		virtual TableAttributeDescListPtr ListTableAttributeDescs(const std::string& tableName);
		virtual std::string sqlesc(const std::string&) const;
		virtual std::string asUnquotedIdentifier(const std::string& identifier) const;
		virtual std::string ConcatenateStatements( const StatementBuilder & statements ) const;
		//@}

		void setSSLConfig(PGSSLConfigPtr config);
		bool isSSLConfig() const;
		void LogSQLStatement( const std::string & sql, long pid );

		static TableAttributeDesc::DType PGatttypeid2DataType(unsigned int atttypeid);

	private:
		boost::scoped_ptr<pqxx::connection> connection;
		PGSSLConfigPtr sslconfig;

		PQXXResultPtr execute(const std::string & sql);
		AbstractDataTablePtr resultToTable(PQXXResultPtr r);
	};
	typedef boost::shared_ptr<PostgresDriver> PostgresDriverPtr;

} //of ns ClientUtils
} //of ns GST

#endif //_POSTGRES_DRIVER_H_